﻿using System;
using Silver3D.Math;

namespace Silver3D.Graphics
{
    public abstract class Camera : Entity
    {
        private double zNear = 0.01, zFar = 1000.0;
        protected Matrix44 projection = Matrix44.Identity;

        protected bool IsProjectionDirty { get; set; }

        /// <summary>
        /// Returns the projection matrix for this camera.
        /// </summary>
        public Matrix44 Projection
        {
            get
            {
                if (IsProjectionDirty)
                {
                    UpdateProjection();
                    IsProjectionDirty = false;
                }
                return projection;
            }
        }

        /// <summary>
        /// Specifies the distance from the viewer to the near clipping plane (always between 0 and ZFar).
        /// </summary>
        public double ZNear
        {
            get { return zNear; }
            set { zNear = value < 0.0 ? 0.0 : value > zFar ? zFar : value; }
        }

        /// <summary>
        /// Specifies the distance from the viewer to the far clipping plane (always greater than ZNear).
        /// </summary>
        public double ZFar
        {
            get { return zFar; }
            set { zFar = value < zNear ? zNear : value; }
        }

        public Camera(Scene scene, string id)
            : base(scene, id)
        {
            IsProjectionDirty = true;
        }

        protected abstract void UpdateProjection();
    }
}
